package io.renren.modules.pdf.controller;

import cn.hutool.core.codec.Base64;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.itextpdf.text.pdf.PdfWriter;
import io.renren.common.exception.RRException;
import io.renren.common.utils.CommonBusinessStatus;
import io.renren.common.utils.R;
import io.renren.modules.pdf.ExportFileUtil;
import io.renren.modules.pdf.entity.*;
import io.renren.modules.pdf.util.StyleUtil;
import io.renren.modules.resumes.dao.ResumeDao;
import io.renren.modules.resumes.entity.ResumeEntity;
import io.renren.modules.resumes.service.ResumeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Locale;
import java.util.UUID;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@RequestMapping("/pdfApi")
@RestController
public class PdfController {


    @Autowired
    private ResumeDao resumeDao;

    @Autowired
    private ResumeService resumeService;

    /*简历头像上传*/
    @PostMapping("/resumeUploadAdvator/{curUserId}")
    public R resumeUploadAdvator(@PathVariable("curUserId")String curUserId,MultipartFile photo, HttpSession session) throws IOException, ClassNotFoundException {
        //获取上传的文件的文件名
        String fileName = photo.getOriginalFilename();
        //处理文件重名问题
        String hzName = fileName.substring(fileName.lastIndexOf("."));
        fileName = UUID.randomUUID().toString() + hzName;
        //获取服务器中photo目录的路径
        //ServletContext servletContext = session.getServletContext();
        //String photoPath = servletContext.getRealPath("photo");

        String photoPath = "E:\\useradvator\\resumeImg\\";

        File file = new File(photoPath);
        if(!file.exists()){
            file.mkdir();
        }
        String finalPath = photoPath + File.separator + fileName;
        //实现上传功能
        photo.transferTo(new File(finalPath));



        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",curUserId);
        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);

        //证明之前的没有保存过简历信息,虽然上传成功了，但是还需要返回一个Base64的编码，可以让页面显示到  TODO
        if (resumeEntity == null){




            return R.ok().put("headImgPath",finalPath);
        }


        //找到序列化的磁盘位置，将这个对象反序列化出来
        String resumeDataPath = resumeEntity.getResumeDataPath();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(resumeDataPath)));

        ResumeEntityDTO resumeEntityDTO = (ResumeEntityDTO) ois.readObject();
        //设置路径头像路径
        resumeEntityDTO.setHeadImgPath(finalPath);


        ResumeEntityDTO newResumeEntityDTO = new ResumeEntityDTO();
        BeanUtils.copyProperties(resumeEntityDTO,newResumeEntityDTO);
        //将这个对象重新反序列化回去
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(resumeDataPath)));
        oos.writeObject(newResumeEntityDTO);

        ois.close();
        oos.close();

        return R.ok().put("headImgPath",finalPath);
    }

    /*这个方法是将图片做成base64编码的格式然后进行返回*/
    @GetMapping("/advatorImg/{userId}")
    public R getAdvatorImgBase64(@PathVariable("userId")String userId) throws IOException, ClassNotFoundException {

        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);

        //证明该用户还没有上传过简历信息, 直接返回即可
        if (resumeEntity == null){
            return R.ok();
        }


        String resumeDataPath = resumeEntity.getResumeDataPath();
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(resumeDataPath)));
        //反序列化出来
        ResumeEntityDTO resumeEntityDTO = (ResumeEntityDTO) ois.readObject();
        //头像存储的本地路径
        String headImgPath = resumeEntityDTO.getHeadImgPath();

        //如果没有发现头像的指定路径，那么将他的头像路径设置成 "" ,并且将他重新序列化回去
        if(null == headImgPath || !new File(headImgPath).exists()){
            resumeEntityDTO.setHeadImgPath(null);

            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(resumeDataPath));
            oos.writeObject(resumeEntityDTO);
            oos.flush();
            oos.close();

            return R.ok();
        }


        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(new File(headImgPath));
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ok().put("data","data:image/jpeg;base64,"+Base64.encode(data));
    }



    @GetMapping("/readPdfFile")
    public void previewPdf(HttpServletResponse response , String fileUrl){
        ExportFileUtil.preview(response, fileUrl);
    }


    /*反序列化出来*/
    @GetMapping("/reflectResumeObj/{userId}")
    public R reflectResumeObj(@PathVariable("userId")String userId){

        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);

        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);

        if (resumeEntity == null){
            return R.error("您还没有填写简历信息，接下来请填写简历信息");
        }



        if (resumeEntity!=null){
            //序列化文件存储的路径
            String resumeDataPath = resumeEntity.getResumeDataPath();
            ResumeEntityDTO resumeEntityDTO = null;
            try {
                ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(resumeDataPath));
                resumeEntityDTO = (ResumeEntityDTO) objectInputStream.readObject();
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }finally {
                if (resumeEntityDTO!=null){
                    return R.ok().put("data",resumeEntityDTO);
                }else{
                    return R.error().put("data","序列化失败,请联系管理员");
                }
            }
        }
        return R.ok();
    }


    /**
     * 简历保存
     * @param resumeEntity
     */
    @PostMapping("/resumeSave")
    public R resumeSave(@RequestBody() ResumeEntityDTO resumeEntity){

        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",resumeEntity.getUserId());
        ResumeEntity resumeObj = resumeDao.selectOne(wrapper);
        if (resumeObj == null){
            try {
                resumeSaves(resumeEntity);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return R.ok();
        }else{
            /*获取到旧的数据保存路径*/
            String savePath = resumeObj.getResumeSavePath();
            String resumeDataPath = resumeObj.getResumeDataPath();

            //删除掉数据库中的旧数据
            resumeDao.delete(wrapper);


            //删除掉原来的旧文件
            File fil1 = new File(savePath);
            File fil2 = new File(resumeDataPath);

            fil1.delete();
            fil2.delete();

            //重新保存新的路径
            try {
                resumeSaves(resumeEntity);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return R.ok();
    }

    private void resumeSaves(ResumeEntityDTO resumeEntity) throws Exception {

        ResumeEntity resumeDo = new ResumeEntity();

        String uuid = UUID.randomUUID().toString().replaceAll("-","");

        //对象序列化的路径
        String dataPath = "E:\\resumedata\\" +uuid + resumeEntity.getName() + ".txt" ; //+ UUID.randomUUID() + "\\" + resumeEntity.getName() + "\\" + resumeEntity.getPhone();
        //对象简历存储的路径
        String resumePath = "E:\\resumepdf\\" +uuid + resumeEntity.getName() + ".pdf"; //；+ UUID.randomUUID() + "\\" + resumeEntity.getName() + "\\" + resumeEntity.getPhone();

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dataPath));
        oos.writeObject(resumeEntity);
        oos.flush();
        oos.close();

        //创建文档
        Document document = new Document(PageSize.A4,5, 5, 36, 36);
        //设置文档保存路径
        PdfWriter.getInstance(document, new FileOutputStream(resumePath));



        document.open();
        Paragraph title = new Paragraph(18f, "个人简历", StyleUtil.myfont(22,Font.BOLD));
        title.setAlignment(Element.ALIGN_CENTER);
        document.add(title);
        document.add(StyleUtil.blankRow(30));

        //基本信息
        PdfPTable tbBaseInfo = new PdfPTable(2);
        PdfPCell cell11 = new PdfPCell(new Paragraph(resumeEntity.getName(),StyleUtil.myfont(18,Font.NORMAL)));
        cell11.setBorder(0);
        //cell11.setPaddingTop(5);
        cell11.setPaddingBottom(10);
        cell11.setPaddingLeft(15);
        //头像
        //String headImgPath = "E:\\元气壁纸缓存\\img\\mm.jpg";
        String headImgPath = resumeEntity.getHeadImgPath();
        if(headImgPath != null){
            Image headImg = Image.getInstance(headImgPath);
            //设置每列宽度比例
            int width11[] = {15,85};
            tbBaseInfo.setWidths(width11);
            tbBaseInfo.getDefaultCell().setBorder(0);
            PdfPCell cellHimg=new PdfPCell();
            cellHimg.setBorder(0);
            cellHimg.setImage(headImg);
            cellHimg.setColspan(1);//合并单元格
            cellHimg.setRowspan(3);
            tbBaseInfo.addCell(cellHimg);
        }
        tbBaseInfo.addCell(cell11);
        String gender = "";
        if ("1".equals(resumeEntity.getGender())){
            gender = "男";
        }else{
            gender = "女";
        }
        PdfPCell cell12 = new PdfPCell(new Paragraph(gender+StyleUtil.splitVline+ resumeEntity.getAge() +"岁"+StyleUtil.splitVline+resumeEntity.getAddress()+StyleUtil.splitVline+resumeEntity.getExpWork()+"年",StyleUtil.myfont(12,Font.NORMAL)));
        cell12.setPaddingBottom(5);
        cell12.setPaddingLeft(15);
        cell12.setBorder(0);
        tbBaseInfo.addCell(cell12);
        PdfPCell cell13 = new PdfPCell(new Paragraph(resumeEntity.getPhone()+StyleUtil.splitVline+ resumeEntity.getWechat() ,StyleUtil.myfont(12,Font.NORMAL)));
        cell13.setBorder(0);
        cell13.setPaddingLeft(15);
        tbBaseInfo.addCell(cell13);
        document.add(tbBaseInfo);



        //加入空行
        document.add(StyleUtil.blankRow(30));

        document.add(StyleUtil.add_headtitle_1("求职意向"));
        //加入空行
        document.add(StyleUtil.blankRow(5));
        //求职意向主体
        PdfPTable careerTable = new PdfPTable(4);
        //配置单元格跨页显示
        careerTable.setSplitLate(false);
        careerTable.setSplitRows(true);

        int careerTableWidth[] = {15,35,15,35};
        careerTable.setWidths(careerTableWidth);
        careerTable.addCell(StyleUtil.add_cell("求职状态：", "#878787",10));

        String jobStatus = "";
        if ("1".equals(resumeEntity.getJobIntentionEntity().getJobStatus())){
            jobStatus = "在职";
        }else if ("2".equals(resumeEntity.getJobIntentionEntity().getJobStatus())){
            jobStatus = "已离职";
        }
        careerTable.addCell(StyleUtil.add_cell(jobStatus,10));
        careerTable.addCell(StyleUtil.add_cell("工作地点：", "#878787",10));
        careerTable.addCell(StyleUtil.add_cell(resumeEntity.getJobIntentionEntity().getJobAddress(),10));

        careerTable.addCell(StyleUtil.add_cell("期望行业：", "#878787",10));
        careerTable.addCell(StyleUtil.add_cell(resumeEntity.getJobIntentionEntity().getExpectIndustry(),10));
        careerTable.addCell(StyleUtil.add_cell("期望职业：", "#878787",10));
        careerTable.addCell(StyleUtil.add_cell(resumeEntity.getJobIntentionEntity().getExpectJob(),10));

        careerTable.addCell(StyleUtil.add_cell("期望薪资：", "#878787",10));
        careerTable.addCell(StyleUtil.add_cell(resumeEntity.getJobIntentionEntity().getExpSalary(),10));
        careerTable.addCell(StyleUtil.add_cell("工作性质：", "#878787",10));
        String jobNature = "";
        if ("1".equals(resumeEntity.getJobIntentionEntity().getJobNature())){
            jobNature = "全职";
        }else if ("2".equals(resumeEntity.getJobIntentionEntity().getJobNature())){
            jobNature = "兼职";
        }else if ("3".equals(resumeEntity.getJobIntentionEntity().getJobNature())){
            jobNature = "实习";
        }

        careerTable.addCell(StyleUtil.add_cell(jobNature,10));
        document.add(careerTable);
        //加入空行
        document.add(StyleUtil.blankRow());



        //工作经验
        document.add(StyleUtil.add_headtitle_1("工作经验"));
        document.add(StyleUtil.blankRow(5));
        //工作经验 主体 Begin
        List<JobExperience> jobExperienceList = resumeEntity.getJobExperience();
        for (JobExperience jobExperience:jobExperienceList){
            StyleUtil.add_workExpTable(document,jobExperience);
        }
        //工作经验 主体 END
        document.add(StyleUtil.blankRow());

        //项目经验
        document.add(StyleUtil.add_headtitle_1("项目经验"));
        document.add(StyleUtil.blankRow(5));
        List<ProjectExperience> projectExperienceList = resumeEntity.getProjectExperienceList();
        for (ProjectExperience projectExperience : projectExperienceList){
            StyleUtil.add_projectExpTable(document,projectExperience);
        }
        //项目经验 主体 END
        document.add(StyleUtil.blankRow());

        //教育经历
        document.add(StyleUtil.add_headtitle_1("教育经历"));
        document.add(StyleUtil.blankRow(5));
        List<EducationEntityDTO> educationEntityList = resumeEntity.getEducationEntityList();
        for (EducationEntityDTO educationEntityDTO:educationEntityList){
            StyleUtil.add_eduExpTable(document,educationEntityDTO);
        }
        //教育经历 END

        document.add(StyleUtil.blankRow());
        //培训经历
        document.add(StyleUtil.add_headtitle_1("培训经历"));
        document.add(StyleUtil.blankRow(5));
        List<TrainingRecord> trainingRecordList = resumeEntity.getTrainingRecordList();
        for (TrainingRecord trainingRecord:trainingRecordList){
            StyleUtil.add_trainExpTable(document,trainingRecord);
        }
        //培训经历 END

        document.add(StyleUtil.blankRow());
        //专业技能
        document.add(StyleUtil.add_headtitle_1("专业技能"));
        document.add(StyleUtil.blankRow(5));
        List<Skillentity> skillentityList = resumeEntity.getSkillentityList();
        for (Skillentity skillentity : skillentityList){
            StyleUtil.add_majorSkillExpTable(document,skillentity);
        }


        document.add(StyleUtil.blankRow());
        //语言能力
        document.add(StyleUtil.add_headtitle_1("语言能力"));
        document.add(StyleUtil.blankRow(5));
        List<LanguageEntity> languageEntities = resumeEntity.getLanguageEntities();
        for (LanguageEntity languageEntity : languageEntities){
            StyleUtil.add_langSkillExpTable(document,languageEntity);
        }


        document.add(StyleUtil.blankRow());
        //语言能力END

        //资格证书
        document.add(StyleUtil.add_headtitle_1("资格证书 "));

        document.add(StyleUtil.blankRow(5));
        List<CertificateEntityDTO> certificateEntityList = resumeEntity.getCertificateEntityList();
        for (CertificateEntityDTO certificateEntityDTO:certificateEntityList){
            StyleUtil.add_certExpTable(document,certificateEntityDTO);
        }

        document.close();

        resumeDo.setResumeDataPath(dataPath);
        resumeDo.setResumeSavePath(resumePath);
        resumeDo.setResumeApproveStatus(CommonBusinessStatus.RESUME_NOT_APPROVE);
        resumeDo.setUserId(Long.parseLong(resumeEntity.getUserId()));
        int isInsert = resumeDao.insert(resumeDo);
        if (isInsert <= 0){
            throw new RRException("简历创建失败");
        }
        System.out.println("创建成功");


    }


    @RequestMapping("/pdfDownHR/{deliveryUserId}")
    public ResponseEntity<byte[]> downResumeResponseHR(HttpSession session,@PathVariable("deliveryUserId")String deliveryUserId) throws IOException {
        QueryWrapper<ResumeEntity> resumeWrapper = new QueryWrapper<>();
        resumeWrapper.eq("user_id",deliveryUserId);
        ResumeEntity resumeEntity = resumeService.getOne(resumeWrapper);

        String resumeSavePath = resumeEntity.getResumeSavePath();
        InputStream is = new FileInputStream(resumeSavePath);
        //创建字节数组
        byte[] bytes = new byte[is.available()];
        //将流读到字节数组中
        is.read(bytes);
        //创建HttpHeaders对象设置响应头信息
        MultiValueMap<String, String> headers = new HttpHeaders();
        //设置要下载方式以及下载文件的名字
        headers.add("Content-Disposition", "attachment;filename=" + "5154bfa1655a49edb37804f08d3dcdb0牛小牛.pdf");
        //设置响应状态码
        HttpStatus statusCode = HttpStatus.OK;
        //创建ResponseEntity对象
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
        //关闭输入流
        is.close();
        return responseEntity;
    }



    @RequestMapping("/pdfDown/{resumeId}")
    public ResponseEntity<byte[]> downResumeResponseEntity(HttpSession session,@PathVariable("resumeId")String resumeId) throws IOException {

        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper();
        wrapper.eq("id",resumeId);
        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);

        String resumeSavePath = resumeEntity.getResumeSavePath();

        //获取ServletContext对象
        //ServletContext servletContext = session.getServletContext();
        //获取服务器中文件的真实路径
        //String realPath = servletContext.getRealPath("/static/img/1.jpg");
        //创建输入流
        InputStream is = new FileInputStream(resumeSavePath);
        //创建字节数组
        byte[] bytes = new byte[is.available()];
        //将流读到字节数组中
        is.read(bytes);
        //创建HttpHeaders对象设置响应头信息
        MultiValueMap<String, String> headers = new HttpHeaders();
        //设置要下载方式以及下载文件的名字
        headers.add("Content-Disposition", "attachment;filename=" + "5154bfa1655a49edb37804f08d3dcdb0牛小牛.pdf");
        //设置响应状态码
        HttpStatus statusCode = HttpStatus.OK;
        //创建ResponseEntity对象
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
        //关闭输入流
        is.close();
        return responseEntity;
    }



    //下面的三个方法是三个预览的方法
    @ResponseBody
    @PostMapping("/pdfStreamReasumeHandeler")
    public R pdfResumeHandelerBase64(@RequestBody FilePathDTO filePathDTO){

        String filePath = filePathDTO.getFilePath();

        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(new File(filePath));
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ok().put("data",Base64.encode(data));
    }
    @ResponseBody
    @RequestMapping(value = "pdfStreamHandeler/{userId}")
    public R pdfStreamHandeler(@PathVariable("userId") String userId) {
        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);
        if (resumeEntity==null){
            throw new RRException("请先上传简历呢");
        }
        //pdf 简历存储的路径
        String filePath = resumeEntity.getResumeSavePath();

        InputStream in = null;
        byte[] data = null;
        int count = 0;
        try {
            in = new FileInputStream(new File(filePath));
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ok().put("data",Base64.encode(data));
    }
    @ResponseBody
    @RequestMapping(value = "/pdfStreamHandelerResumeId/{resumeId}")
    public R pdfStreamHandelerResumeId(@PathVariable("resumeId")String resumeId) {
        QueryWrapper<ResumeEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("id", resumeId);

        ResumeEntity resumeEntity = resumeDao.selectOne(wrapper);
        if (resumeEntity==null){
            throw new RRException("请先上传简历呢");
        }

        resumeEntity.setResumeApproveStatus(CommonBusinessStatus.RESUME_HAVEING_APPROVE);
        resumeDao.updateById(resumeEntity);


        //pdf 简历存储的路径
        String filePath = resumeEntity.getResumeSavePath();

        InputStream in = null;
        byte[] data = null;
        int count = 0;
        try {
            in = new FileInputStream(new File(filePath));
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.ok().put("data",Base64.encode(data));
    }
}
